package org.jsola.hr.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.jsola.common.DateKit;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.ConfigCodeConstants;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.*;
import org.jsola.hr.dto.SalaryBillSendAddDTO;
import org.jsola.hr.dto.SalaryBillSendUpdateDTO;
import org.jsola.hr.dto.TaskAddDTO;
import org.jsola.hr.entity.*;
import org.jsola.hr.provider.ISiteConfigProviderService;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.hr.query.SalaryBillSendQuery;
import org.jsola.hr.query.SalaryBillSendRelQuery;
import org.jsola.hr.service.ISalaryBillSendService;
import org.jsola.hr.service.ITaskService;
import org.jsola.hr.task.HrSalaryBillTask;
import org.jsola.hr.vo.*;
import org.jsola.user.core.TokenUser;
import org.jsola.user.entity.UnionOpenIdDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工资条发放信息
 *
 * @author zhr
 */
@Service("hrSalaryBillSendServiceImpl")
public class SalaryBillSendServiceImpl implements ISalaryBillSendService {

    @Autowired
    private ISalaryBillSendDAO salaryBillSendDAO;

    @Autowired
    private ISalaryBillFieldsDAO salaryBillFieldsDAO;

    @Autowired
    private ISalaryBillSendRelDAO salaryBillSendRelDAO;

    @Autowired
    private IEmpInfoDAO empInfoDAO;

    @Autowired
    private IUserProviderService userProviderService;

    @Autowired
    private HrSalaryBillTask hrSalaryBillTask;

    @Autowired
    private ISalaryBillDAO salaryBillDAO;

    @Autowired
    private ITaskService taskService;

    @Autowired
    private ThreadPoolTaskScheduler threadPoolTask;

    @Autowired
    private ISiteConfigProviderService siteConfigProviderService;


    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public SalaryBillSendVO save(SalaryBillSendAddDTO salaryBillSendAddDTO, TokenUser tokenUser) {
        // 当前时间
        Date now = DateKit.getToday();

        // 转DO
        SalaryBillSendDO salaryBillSendDO = salaryBillSendAddDTO.to(SalaryBillSendDO.class);
        Example exampleSendName = new Example(SalaryBillSendDO.class);
        exampleSendName.and()
                .andEqualTo("companyId", salaryBillSendDO.getCompanyId())
                .andEqualTo("tableId", salaryBillSendDO.getTableId());
        Integer sendCount = salaryBillSendDAO.selectCountByExample(exampleSendName);
        salaryBillSendDO.setSendName("第" + (sendCount + 1) + "次发放");
        salaryBillSendDO.setSendBy(tokenUser.getUserName());
        salaryBillSendDO.setSendTime(now);
        salaryBillSendDO.setWithdrawStatus(false);
        // 保存
        salaryBillSendDO = save(salaryBillSendDO, tokenUser.getSiteId(), tokenUser.getUserId());

        // 保存发放记录和工资条关联
        List<SalaryBillSendRelDO> salaryBillSendRelDOList = new ArrayList<>();
        // 工资条ID集合
        List<String> salaryBillIdList = new ArrayList<>();
        List<BillSendInfoVO> openIdList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(salaryBillSendAddDTO.getSalaryBillDOList())) {
            SalaryBillSendDO finalSalaryBillSendDO = salaryBillSendDO;
            Date runDate = now;
            if (salaryBillSendDO.getAutoCheckUnit() == 1) {
                // 按小时
                runDate = DateKit.getBeforeMinute(now, salaryBillSendDO.getAutoCheckHours() * 60);
            } else if (salaryBillSendDO.getAutoCheckUnit() == 2) {
                // 按天
                runDate = DateKit.getBeforeDay(now, salaryBillSendDO.getAutoCheckHours());
            }
            Date finalRunDate = runDate;
            salaryBillSendAddDTO.getSalaryBillDOList().stream().filter(item -> Boolean.TRUE.equals(item.getSendStatus())).forEach(item -> {
                SalaryBillSendRelDO salaryBillSendRelDO = new SalaryBillSendRelDO();
                salaryBillSendRelDO.setSendId(finalSalaryBillSendDO.getId());
                salaryBillSendRelDO.setBillId(item.getId());
                salaryBillSendRelDO.setSendStatus(item.getSendStatus());
                salaryBillSendRelDO.setWithdrawStatus(false);
                salaryBillSendRelDO.setAutoCheckTime(finalRunDate);
                salaryBillSendRelDO.setValid(true);
                salaryBillSendRelDO.setGmtCreate(now);
                salaryBillSendRelDO.setGmtModified(now);
                salaryBillSendRelDO.setCreateUserId(tokenUser.getUserId());
                salaryBillSendRelDO.setModifiedUserId(tokenUser.getUserId());
                salaryBillSendRelDO.setSiteId(tokenUser.getSiteId());
                salaryBillSendRelDOList.add(salaryBillSendRelDO);
                salaryBillIdList.add(item.getId());

                // 根据unionId和appId查询员工openId
                EmpInfoDO empInfoDO = empInfoDAO.selectByPrimaryKey(item.getEmpId());
                if (Objects.nonNull(empInfoDO)) {
                    String appid = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_APPID, tokenUser.getSiteId());
                    UnionOpenIdDO unionOpenIdDO = userProviderService.getUnionOpenByUserId(appid, empInfoDO.getUserId());
                    if (Objects.nonNull(unionOpenIdDO) && StringUtils.isNotBlank(unionOpenIdDO.getOpenId())) {
                        BillSendInfoVO sendInfo = new BillSendInfoVO();
                        sendInfo.setOpenId(unionOpenIdDO.getOpenId());
                        sendInfo.setBillId(item.getId());
                        openIdList.add(sendInfo);
                    }
                }
            });
            salaryBillSendRelDAO.insertListAndSetId(salaryBillSendRelDOList);

            // 更新工资条发放状态
            Example example = new Example(SalaryBillDO.class);
            example.and()
                    .andIn("id", salaryBillIdList)
                    .andEqualTo("valid", true);
            SalaryBillDO salaryBillDO = new SalaryBillDO();
            salaryBillDO.setSendStatus(true);
            salaryBillDO.setSendType(salaryBillSendDO.getSendType());
            salaryBillDO.setSendTime(now);
            salaryBillDAO.updateByExampleSelective(salaryBillDO, example);

            // 添加定时任务记录,重启时处理
            TaskAddDTO taskAddDTO = new TaskAddDTO();
            taskAddDTO.setSubjectType("salaryBillAutoCheck");
            taskAddDTO.setSubjectId(salaryBillSendDO.getId());
            taskAddDTO.setDescription("工资条发放到期自动确认");
            taskAddDTO.setRunBeanName("salaryBillSendServiceImpl");
            taskAddDTO.setStatus(false);
            taskAddDTO.setRunDate(runDate);
            TaskVO taskVO = taskService.save(taskAddDTO, tokenUser);
            // 添加运行定时任务
            Runnable runnable = new SalaryBillAutoCheckTask(taskVO.getId());
            threadPoolTask.schedule(runnable, runDate);

            // 批量推送微信模板消息
//            Integer successCount = sendWeChatTemplateMessage(openIdList, salaryBillSendAddDTO, tokenUser);
            Integer successCount = openIdList.size();
            salaryBillSendAddDTO.setSubjectId(salaryBillSendDO.getId());
            hrSalaryBillTask.sendWeChatTemplateMessage(openIdList, salaryBillSendAddDTO, tokenUser);
            salaryBillSendDO.setSendCount(successCount);
        }
        SalaryBillSendVO salaryBillSendVO = salaryBillSendDO.to(SalaryBillSendVO.class);
        salaryBillSendVO.setYear(salaryBillSendAddDTO.getYear());
        salaryBillSendVO.setMonth(salaryBillSendAddDTO.getMonth());
        return salaryBillSendVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(SalaryBillSendUpdateDTO salaryBillSendUpdateDTO, TokenUser tokenUser) {
        //转DO
        SalaryBillSendDO salaryBillSendDO = salaryBillSendUpdateDTO.to(SalaryBillSendDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(salaryBillSendDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... salaryBillSendIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) salaryBillSendIds);
    }


    @Override
    public SalaryBillSendVO selectById(String salaryBillSendId, String siteId) {
        SalaryBillSendDO salaryBillSendDO = selectDOById(salaryBillSendId, siteId);
        if (salaryBillSendDO == null) {
            return null;
        }
        return salaryBillSendDO.to(SalaryBillSendVO.class);
    }

    @Override
    public List<SalaryBillSendListVO> select(SalaryBillSendQuery salaryBillSendQuery, String siteId) {
        List<SalaryBillSendDO> salaryBillSendDOList = selectDO(salaryBillSendQuery, siteId);
        if (CollectionUtils.isEmpty(salaryBillSendDOList)) {
            return salaryBillSendDOList == null ? null : new ArrayList<>();
        }
        return salaryBillSendDOList.stream()
                .map(salaryBillSendDO -> salaryBillSendDO.to(SalaryBillSendListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(SalaryBillSendQuery salaryBillSendQuery, String siteId) {
        Example example = buildExample(salaryBillSendQuery, siteId);
        return salaryBillSendDAO.selectCountByExample(example);
    }

    @Override
    public Page<SalaryBillSendListVO> selectPage(SalaryBillSendQuery salaryBillSendQuery, String siteId) {
        Example example = buildExample(salaryBillSendQuery, siteId);
        Page<SalaryBillSendDO> page = salaryBillSendDAO.selectPageByExample(example,
                salaryBillSendQuery.getPageNo(),
                salaryBillSendQuery.getPageSize());

        return page.to(SalaryBillSendListVO.class);
    }

    @Override
    public SalaryBillSendDO selectDOById(String salaryBillSendId, String siteId) {
        return listById(salaryBillSendId, siteId);
    }

    @Override
    public List<SalaryBillSendDO> selectDO(SalaryBillSendQuery salaryBillSendQuery, String siteId) {
        Example example = buildExample(salaryBillSendQuery, siteId);
        return salaryBillSendDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example
     *
     * @param salaryBillSendQuery 查询参数
     * @param siteId              所属站点id
     * @return example
     */
    private Example buildExample(SalaryBillSendQuery salaryBillSendQuery, String siteId) {
        Example example = new Example(SalaryBillSendDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (salaryBillSendQuery.getTableId() != null) {
            example.and().andEqualTo("tableId", salaryBillSendQuery.getTableId());
        }
        if (salaryBillSendQuery.getSendType() != null) {
            example.and().andEqualTo("sendType", salaryBillSendQuery.getSendType());
        }
        if (salaryBillSendQuery.getAutoCheckHours() != null) {
            example.and().andEqualTo("autoCheckHours", salaryBillSendQuery.getAutoCheckHours());
        }
        if (salaryBillSendQuery.getAutoCheckUnit() != null) {
            example.and().andEqualTo("autoCheckUnit", salaryBillSendQuery.getAutoCheckUnit());
        }
        if (salaryBillSendQuery.getShowEmptyValue() != null) {
            example.and().andEqualTo("showEmptyValue", salaryBillSendQuery.getShowEmptyValue());
        }
        if (salaryBillSendQuery.getSendName() != null) {
            example.and().andEqualTo("sendName", salaryBillSendQuery.getSendName());
        }
        if (salaryBillSendQuery.getSendBy() != null) {
            example.and().andEqualTo("sendBy", salaryBillSendQuery.getSendBy());
        }
        if (salaryBillSendQuery.getSendTimeStart() != null &&
                salaryBillSendQuery.getSendTimeEnd() != null) {
            example.and().andBetween("sendTime", salaryBillSendQuery.getSendTimeStart(),
                    salaryBillSendQuery.getSendTimeEnd());
        }
        if (salaryBillSendQuery.getSendCount() != null) {
            example.and().andEqualTo("sendCount", salaryBillSendQuery.getSendCount());
        }
        if (salaryBillSendQuery.getReadCount() != null) {
            example.and().andEqualTo("readCount", salaryBillSendQuery.getReadCount());
        }
        if (salaryBillSendQuery.getCheckCount() != null) {
            example.and().andEqualTo("checkCount", salaryBillSendQuery.getCheckCount());
        }
        if (salaryBillSendQuery.getFeedbackCount() != null) {
            example.and().andEqualTo("feedbackCount", salaryBillSendQuery.getFeedbackCount());
        }
        if (salaryBillSendQuery.getWithdrawnCount() != null) {
            example.and().andEqualTo("withdrawnCount", salaryBillSendQuery.getWithdrawnCount());
        }
        if (salaryBillSendQuery.getWithdrawStatus() != null) {
            example.and().andEqualTo("withdrawStatus", salaryBillSendQuery.getWithdrawStatus());
        }
        if (salaryBillSendQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", salaryBillSendQuery.getCompanyId());
        }
        // 排序
        ExampleKit.setExampleOrder(example, salaryBillSendQuery.getOrders());
        return example;
    }

    @Override
    public SalaryBillSendVO salaryBillSendDetailTab(SalaryBillSendQuery salaryBillSendQuery, String siteId) {
        return salaryBillSendDAO.salaryBillSendDetailTab(salaryBillSendQuery, siteId);
    }

    @Override
    public Page<SalaryBillSendListVO> salaryBillSendListPage(SalaryBillSendQuery salaryBillSendQuery, String siteId) {
        PageInfo<SalaryBillSendListVO> pageInfo = PageHelper.startPage(salaryBillSendQuery.getPageNo(), salaryBillSendQuery.getPageSize()).doSelectPageInfo(() -> {
            salaryBillSendDAO.selectSalaryBillSendList(salaryBillSendQuery);
        });
        return new Page(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), (int) pageInfo.getTotal());
    }

    @Override
    public Page<SalaryBillListVO> salaryBillListPageBySend(SalaryBillSendRelQuery salaryBillSendRelQuery, String siteId) {
        PageInfo<SalaryBillListVO> pageInfo = PageHelper.startPage(salaryBillSendRelQuery.getPageNo(), salaryBillSendRelQuery.getPageSize()).doSelectPageInfo(() -> {
            salaryBillDAO.salaryBillListPageBySend(salaryBillSendRelQuery);
        });
        List<SalaryBillListVO> list = pageInfo.getList();


        // 查询工资条自定义字段列表
        if (!CollectionUtils.isEmpty(list)) {
            List<String> billIdList;
            billIdList = list.stream().map(SalaryBillListVO::getId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(billIdList)) {
                Example exampleField = new Example(SalaryBillFieldsDO.class);
                exampleField.and().andIn("billId", billIdList);
                exampleField.orderBy("sort");

                List<SalaryBillFieldsDO> salaryBillFieldsDOList = salaryBillFieldsDAO.selectByExample(exampleField);
                // 工资条-自定义工资项Map
                Map<String, List<SalaryBillFieldsDO>> billIdSalaryBillFieldsDOMap = salaryBillFieldsDOList.stream()
                        .collect(Collectors.groupingBy(SalaryBillFieldsDO::getBillId));
                // 返回到列表中
                list.forEach(item -> {
                    // 根据tableId查找发放记录
                    SalaryBillSendDO salaryBillSendDO = findByTableId(item.getTableId(), siteId);
                    // 根据Id查找工资条记录
                    SalaryBillDO salaryBillDO = find(item.getId(), siteId);
                    if (salaryBillDO == null) {
                        return;
                    }
                    // 是否显示空值
                    boolean showEmptyValue;
                    if (Objects.nonNull(salaryBillSendDO)) {
                        showEmptyValue = salaryBillSendDO.getShowEmptyValue();
                    } else {
                        showEmptyValue = false;
                    }
                    item.setCheckTime(salaryBillDO.getCheckTime());
                    item.setShowEmptyValue(showEmptyValue);
                    List<SalaryBillFieldsDO> setSalaryBillFieldsDOList = billIdSalaryBillFieldsDOMap.get(item.getId());
                    if (CollectionUtils.isEmpty(setSalaryBillFieldsDOList)) {
                        item.setSalaryBillFieldsDOList(setSalaryBillFieldsDOList);
                        return;
                    }
                    List<SalaryBillFieldsDO> collect = setSalaryBillFieldsDOList.stream().filter(salaryBillFieldsDO -> {
                        // 电子工资条查询 去除自定义项中基本工资 放入对象属性中
                        if ("基本工资".equals(salaryBillFieldsDO.getFieldName())) {
                            item.setSalaryBasic(new BigDecimal(salaryBillFieldsDO.getFieldValue()));
                            return false;
                        }
                        // 不过滤空值 直接返回
                        if (showEmptyValue) {
                            return true;
                        }
                        // 过滤空置
                        if (StringUtils.isBlank(salaryBillFieldsDO.getFieldValue())) {
                            return false;
                        }
                        // 过滤0及0.00
                        String replaceAll = salaryBillFieldsDO.getFieldValue().replaceAll("0", "");
                        return !StringUtils.isBlank(replaceAll) && !".".equals(replaceAll);
                    }).collect(Collectors.toList());
                    item.setSalaryBillFieldsDOList(collect);
                });
            }
        }
        return new Page<>(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), (int) pageInfo.getTotal());
    }

    /**
     * 根据tableId查找发放记录
     *
     * @param tableId 表id
     * @param siteId  站点id
     * @return 发放记录
     */
    private SalaryBillSendDO findByTableId(String tableId, String siteId) {
        Example example = new Example(SalaryBillSendDO.class);
        example.and()
                .andEqualTo("tableId", tableId)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        // 取最后一次发放记录
        example.orderBy("gmtCreate").desc();
        List<SalaryBillSendDO> salaryBillSendList = salaryBillSendDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(salaryBillSendList)) {
            return null;
        }
        return salaryBillSendList.get(0);
    }

    /**
     * 根据id查找工资条记录
     *
     * @param id     数据id
     * @param siteId 站点id
     * @return 发放记录
     */
    private SalaryBillDO find(String id, String siteId) {
        Example example = new Example(SalaryBillDO.class);
        example.and()
                .andEqualTo("id", id)
                .andEqualTo("siteId", siteId);
        List<SalaryBillDO> salaryBillDOList = salaryBillDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(salaryBillDOList)) {
            return null;
        }
        return salaryBillDOList.get(0);
    }

    @Override
    public Page<SalaryBillListVO> salaryBillPageBySendDetail(SalaryBillSendRelQuery salaryBillSendRelQuery, String siteId) {
        PageInfo<SalaryBillListVO> pageInfo = PageHelper.startPage(salaryBillSendRelQuery.getPageNo(), salaryBillSendRelQuery.getPageSize()).doSelectPageInfo(() -> {
            salaryBillDAO.salaryBillPageBySendDetail(salaryBillSendRelQuery);
        });
        // 查询工资条自定义字段列表
        if (!CollectionUtils.isEmpty(pageInfo.getList())) {
            List<String> billIdList = new ArrayList<>();
            billIdList = pageInfo.getList().stream().map(item -> item.getId()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(billIdList)) {
                Example exampleField = new Example(SalaryBillFieldsDO.class);
                exampleField.and().andIn("billId", billIdList);
                exampleField.orderBy("sort");

                List<SalaryBillFieldsDO> salaryBillFieldsDOList = salaryBillFieldsDAO.selectByExample(exampleField);
                // 返回到列表中
                pageInfo.getList().forEach(item -> {
                    List<SalaryBillFieldsDO> salaryBillFieldsDOListTmp = new ArrayList<>();
                    salaryBillFieldsDOList.forEach(itemChild -> {
                        if (item.getId().equals(itemChild.getBillId())) {
                            if ("基本工资".equals(itemChild.getFieldName())) {
                                try {
                                    item.setSalaryBasic(new BigDecimal(itemChild.getFieldValue()));
                                } catch (Exception e) {
                                    throw new ParamException("基本工资有误");
                                }
                                return;
                            }
                            salaryBillFieldsDOListTmp.add(itemChild);
                        }
                    });
                    item.setSalaryBillFieldsDOList(salaryBillFieldsDOListTmp);
                });
            }
        }
        return new Page(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), (int) pageInfo.getTotal());
    }

    @Override
    public List<SalaryBillListVO> allSalaryBillSendDetail(SalaryBillSendRelQuery salaryBillSendRelQuery, String siteId) {
        List<SalaryBillListVO> salaryBillListVOList = salaryBillDAO.salaryBillListPageBySend(salaryBillSendRelQuery);
        // 查询工资条自定义字段列表
        if (!CollectionUtils.isEmpty(salaryBillListVOList)) {
            List<String> billIdList = new ArrayList<>();
            billIdList = salaryBillListVOList.stream().map(SalaryBillListVO::getId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(billIdList)) {
                Example exampleField = new Example(SalaryBillFieldsDO.class);
                exampleField.and().andIn("billId", billIdList);
                exampleField.orderBy("sort");

                List<SalaryBillFieldsDO> salaryBillFieldsDOList = salaryBillFieldsDAO.selectByExample(exampleField);
                // 返回到列表中
                salaryBillListVOList.forEach(item -> {
                    List<SalaryBillFieldsDO> salaryBillFieldsDOListTmp = new ArrayList<>();
                    salaryBillFieldsDOList.forEach(itemChild -> {
                        if (item.getId().equals(itemChild.getBillId())) {
                            salaryBillFieldsDOListTmp.add(itemChild);
                        }
                    });
                    item.setSalaryBillFieldsDOList(salaryBillFieldsDOListTmp);
                });
            }
        }
        return salaryBillListVOList;
    }

    @Override
    public Integer withdraw(SalaryBillSendUpdateDTO salaryBillSendUpdateDTO, TokenUser tokenUser) {
        //转DO
        SalaryBillSendDO salaryBillSendDO = salaryBillSendUpdateDTO.to(SalaryBillSendDO.class);
        //根据主键更新，只更新非null值
        salaryBillSendDO.setWithdrawStatus(true);
        //更新工资条状态
        List<String> salaryBillIdList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(salaryBillSendUpdateDTO.getSalaryBillDOList())) {
            salaryBillSendUpdateDTO.getSalaryBillDOList().parallelStream().forEach(item -> {
                salaryBillIdList.add(item.getId());
            });
            // 当前时间
            Date now = DateKit.getToday();
            SalaryBillDO salaryBillDO = new SalaryBillDO();
            salaryBillDO.setWithdrawnStatus(true);
            salaryBillDO.setWithdrawnTime(now);
            Example example = new Example(SalaryBillSendDO.class);
            example.and()
                    .andEqualTo("valid", true)
                    .andIn("id", salaryBillIdList);
            salaryBillDAO.updateByExampleSelective(salaryBillDO, example);
        }

        //更新工资条发放信息关联
        SalaryBillSendRelDO salaryBillSendRelDO = new SalaryBillSendRelDO();
        salaryBillSendRelDO.setWithdrawStatus(true);
        Example example = new Example(SalaryBillSendRelDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("sendId", salaryBillSendDO.getId())
                .andIn("billId", salaryBillIdList);
        salaryBillSendRelDAO.updateByExampleSelective(salaryBillSendRelDO, example);

        return updateByIdSelective(salaryBillSendDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    public Integer updateSalaryBillStatus(String subjectId, TokenUser tokenUser) {
        // 更新工资条发放信息关联
        Example example = new Example(SalaryBillSendRelDO.class);
        example.and()
                .andEqualTo("sendId", subjectId)
                .andEqualTo("sendStatus", 1)
                .andEqualTo("valid", true);
        SalaryBillSendRelDO salaryBillSendRelDO = new SalaryBillSendRelDO();
        salaryBillSendRelDO.setCheckStatus(true);
        salaryBillSendRelDAO.updateByExampleSelective(salaryBillSendRelDO, example);

        // 更新工资条记录
        Example exampleSalaryBill = new Example(SalaryBillDO.class);
        exampleSalaryBill.and()
                .andCondition("id in (select bill_id from hr_salary_bill_send_rel where send_id = '" + subjectId + "' and send_status = 1 and is_valid = 1)");
        SalaryBillDO salaryBillDO = new SalaryBillDO();
        salaryBillDO.setCheckStatus(true);
        salaryBillDO.setCheckTime(DateKit.getToday());
        Integer count = salaryBillDAO.updateByExampleSelective(salaryBillDO, exampleSalaryBill);
        return count;
    }

    public class SalaryBillAutoCheckTask implements Runnable {
        private String taskId;

        SalaryBillAutoCheckTask(String taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            TaskDO task = taskService.selectDOById(taskId, "");
            if (Objects.nonNull(task)) {
                hrSalaryBillTask.runTask(taskId);
            }
        }
    }

}




